package com.example.mydy.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import com.example.mydy.model.ActivityData;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

/**
 * 用户活跃度管理类
 */
public class ActivityManager {
    private static final String TAG = "ActivityManager";
    private static final String PREFS_NAME = "ActivityPrefs";
    private static final String KEY_ACTIVITIES = "user_activities";
    private static final String KEY_LAST_CHECK_DATE = "last_check_date";
    private static final String KEY_DAILY_REWARD_CLAIMED = "daily_reward_claimed";
    
    private SharedPreferences prefs;
    private Map<String, ActivityData> activityDataMap;
    private static ActivityManager instance;
    
    private final Gson gson = new Gson();
    private Context context;
    
    // 私有构造函数，实现单例模式
    private ActivityManager(Context context) {
        this.context = context.getApplicationContext();
        prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        activityDataMap = new HashMap<>();
        loadActivitiesData();
        checkDateChange();
    }
    
    /**
     * 获取ActivityManager实例
     */
    public static synchronized ActivityManager getInstance(Context context) {
        if (instance == null) {
            instance = new ActivityManager(context);
        }
        return instance;
    }
    
    /**
     * 加载所有用户的活跃度数据
     */
    private void loadActivitiesData() {
        String activitiesJson = prefs.getString(KEY_ACTIVITIES, "");
        if (!activitiesJson.isEmpty()) {
            try {
                Type type = new TypeToken<Map<String, ActivityData>>() {}.getType();
                Map<String, ActivityData> loadedData = gson.fromJson(activitiesJson, type);
                if (loadedData != null) {
                    activityDataMap = loadedData;
                }
            } catch (Exception e) {
                Log.e(TAG, "加载活跃度数据失败: " + e.getMessage(), e);
                activityDataMap = new HashMap<>();
            }
        }
    }
    
    /**
     * 保存所有用户的活跃度数据
     */
    private void saveActivitiesData() {
        String activitiesJson = gson.toJson(activityDataMap);
        prefs.edit().putString(KEY_ACTIVITIES, activitiesJson).apply();
    }
    
    /**
     * 检查日期变更，重置相关数据
     */
    private void checkDateChange() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
        String today = dateFormat.format(new Date());
        String lastCheckDate = prefs.getString(KEY_LAST_CHECK_DATE, "");
        
        if (!today.equals(lastCheckDate)) {
            // 新的一天，重置每日活跃度
            resetDailyData();
            prefs.edit().putString(KEY_LAST_CHECK_DATE, today).apply();
        }
        
        // 检查是否是新的一周或新的一月
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        
        if (dayOfWeek == Calendar.MONDAY && !today.equals(lastCheckDate)) {
            // 新的一周，重置周活跃度
            resetWeeklyData();
        }
        
        if (dayOfMonth == 1 && !today.equals(lastCheckDate)) {
            // 新的一月，重置月活跃度
            resetMonthlyData();
        }
    }
    
    /**
     * 重置每日活跃度数据
     */
    private void resetDailyData() {
        for (ActivityData activityData : activityDataMap.values()) {
            activityData.resetDailyActivity();
        }
        saveActivitiesData();
        
        // 重置每日奖励领取状态
        prefs.edit().putBoolean(KEY_DAILY_REWARD_CLAIMED, false).apply();
    }
    
    /**
     * 重置每周活跃度数据
     */
    private void resetWeeklyData() {
        for (ActivityData activityData : activityDataMap.values()) {
            activityData.resetWeeklyActivity();
        }
        saveActivitiesData();
    }
    
    /**
     * 重置每月活跃度数据
     */
    private void resetMonthlyData() {
        for (ActivityData activityData : activityDataMap.values()) {
            activityData.resetMonthlyActivity();
        }
        saveActivitiesData();
    }
    
    /**
     * 获取指定用户的活跃度数据
     * @param username 用户名
     * @return 用户活跃度数据
     */
    public ActivityData getActivityData(String username) {
        // 如果没有找到用户数据，创建一个新的
        if (!activityDataMap.containsKey(username)) {
            ActivityData newData = new ActivityData(0, username);
            activityDataMap.put(username, newData);
            saveActivitiesData();
        }
        return activityDataMap.get(username);
    }
    
    /**
     * 用户登录时调用，记录登录活跃度
     * @param username 用户名
     * @return 连续登录天数
     */
    public int userLogin(String username) {
        checkDateChange();
        ActivityData activityData = getActivityData(username);
        activityData.login();
        saveActivitiesData();
        return activityData.getConsecutiveLogins();
    }
    
    /**
     * 用户提交任务时调用
     * @param username 用户名
     */
    public void submitTask(String username) {
        ActivityData activityData = getActivityData(username);
        activityData.submitTask();
        saveActivitiesData();
    }
    
    /**
     * 用户完成悬赏时调用
     * @param username 用户名
     */
    public void completeReward(String username) {
        ActivityData activityData = getActivityData(username);
        activityData.completeReward();
        saveActivitiesData();
    }
    
    /**
     * 增加用户活跃度
     * @param username 用户名
     * @param points 增加的活跃度点数
     */
    public void addActivityPoints(String username, int points) {
        ActivityData activityData = getActivityData(username);
        activityData.addDailyActivity(points);
        saveActivitiesData();
    }
    
    /**
     * 获取用户活跃度等级名称
     * @param username 用户名
     * @return 等级名称
     */
    public String getUserActivityLevelName(String username) {
        ActivityData activityData = getActivityData(username);
        return activityData.getActivityLevelName();
    }
    
    /**
     * 获取用户距离下一等级所需活跃度
     * @param username 用户名
     * @return 所需活跃度点数
     */
    public int getNextLevelRequiredActivity(String username) {
        ActivityData activityData = getActivityData(username);
        return activityData.getNextLevelRequiredActivity();
    }
    
    /**
     * 检查用户今日是否已签到
     * @param username 用户名
     * @return 是否已签到
     */
    public boolean isUserCheckedInToday(String username) {
        ActivityData activityData = getActivityData(username);
        return activityData.isCheckedInToday();
    }
    
    /**
     * 获取用户连续登录天数
     * @param username 用户名
     * @return 连续登录天数
     */
    public int getUserConsecutiveLogins(String username) {
        ActivityData activityData = getActivityData(username);
        return activityData.getConsecutiveLogins();
    }
    
    /**
     * 获取用户当前活跃度等级
     * @param username 用户名
     * @return 活跃度等级(1-5)
     */
    public int getUserActivityLevel(String username) {
        ActivityData activityData = getActivityData(username);
        return activityData.getActivityLevel();
    }
    
    /**
     * 计算用户今日可获得的奖励金额
     * @param username 用户名
     * @return 今日可获得的奖励金额
     */
    public double calculateDailyReward(String username) {
        ActivityData activityData = getActivityData(username);
        double baseReward = 0.1; // 基础奖励0.1元
        
        // 连续登录奖励
        int consecutiveLogins = activityData.getConsecutiveLogins();
        double loginBonus = Math.min(consecutiveLogins * 0.02, 0.5); // 最多0.5元
        
        // 活跃等级奖励
        double levelBonus = (activityData.getActivityLevel() - 1) * 0.1; // 每提升一级增加0.1元
        
        // 活跃度点数奖励
        double activityBonus = activityData.getDailyActivity() * 0.005; // 每点活跃度增加0.005元
        
        return baseReward + loginBonus + levelBonus + activityBonus;
    }
    
    /**
     * 领取每日奖励
     * @param username 用户名
     * @return 奖励金额，如果今日已领取则返回0
     */
    public double claimDailyReward(String username) {
        boolean alreadyClaimed = prefs.getBoolean(KEY_DAILY_REWARD_CLAIMED, false);
        if (alreadyClaimed) {
            return 0;
        }
        
        double reward = calculateDailyReward(username);
        prefs.edit().putBoolean(KEY_DAILY_REWARD_CLAIMED, true).apply();
        
        // 更新用户余额（在实际应用中，这应该调用相应的用户账户管理服务）
        // userAccountService.addBalance(username, reward);
        
        return reward;
    }
    
    /**
     * 获取活跃度排行榜
     * @param type 排行榜类型: "daily", "weekly", "monthly"
     * @param limit 返回数量限制
     * @return 排行榜数据
     */
    public List<Map<String, Object>> getActivityRanking(String type, int limit) {
        List<ActivityData> sortedActivities = new ArrayList<>(activityDataMap.values());
        
        // 根据类型排序
        if ("daily".equals(type)) {
            sortedActivities.sort((a1, a2) -> Integer.compare(a2.getDailyActivity(), a1.getDailyActivity()));
        } else if ("weekly".equals(type)) {
            sortedActivities.sort((a1, a2) -> Integer.compare(a2.getWeeklyActivity(), a1.getWeeklyActivity()));
        } else { // monthly
            sortedActivities.sort((a1, a2) -> Integer.compare(a2.getMonthlyActivity(), a1.getMonthlyActivity()));
        }
        
        // 限制返回数量
        int count = Math.min(sortedActivities.size(), limit);
        
        // 构建结果
        List<Map<String, Object>> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            ActivityData data = sortedActivities.get(i);
            Map<String, Object> item = new HashMap<>();
            item.put("rank", i + 1);
            item.put("username", data.getUsername());
            item.put("level", data.getActivityLevel());
            item.put("levelName", data.getActivityLevelName());
            
            // 根据类型添加活跃度
            if ("daily".equals(type)) {
                item.put("activity", data.getDailyActivity());
            } else if ("weekly".equals(type)) {
                item.put("activity", data.getWeeklyActivity());
            } else { // monthly
                item.put("activity", data.getMonthlyActivity());
            }
            
            result.add(item);
        }
        
        return result;
    }
    
    /**
     * 生成测试数据（仅用于开发测试）
     */
    public void generateTestData() {
        // 创建一些测试用户
        String[] testUsers = {"user1", "user2", "user3", "user4", "user5"};
        Random random = new Random();
        
        for (String username : testUsers) {
            if (!activityDataMap.containsKey(username)) {
                ActivityData data = new ActivityData(random.nextInt(1000), username);
                
                // 设置随机活跃度数据
                data.setDailyActivity(random.nextInt(100));
                data.setWeeklyActivity(data.getDailyActivity() + random.nextInt(200));
                data.setMonthlyActivity(data.getWeeklyActivity() + random.nextInt(500));
                data.setConsecutiveLogins(random.nextInt(10));
                data.setTotalTasksSubmitted(random.nextInt(50));
                data.setTotalRewardsCompleted(random.nextInt(30));
                
                // 更新活跃度等级
                if (data.getMonthlyActivity() >= 1000) {
                    data.setActivityLevel(5);
                } else if (data.getMonthlyActivity() >= 500) {
                    data.setActivityLevel(4);
                } else if (data.getMonthlyActivity() >= 200) {
                    data.setActivityLevel(3);
                } else if (data.getMonthlyActivity() >= 50) {
                    data.setActivityLevel(2);
                } else {
                    data.setActivityLevel(1);
                }
                
                activityDataMap.put(username, data);
            }
        }
        
        saveActivitiesData();
    }
    
    /**
     * 获取月度活跃度排行榜
     * @param limit 返回数量限制
     * @return 排行榜数据
     */
    public List<ActivityData> getMonthlyRankings(int limit) {
        List<ActivityData> activityDataList = new ArrayList<>(activityDataMap.values());
        
        // 按月活跃度降序排序
        activityDataList.sort((a1, a2) -> Integer.compare(a2.getMonthlyActivity(), a1.getMonthlyActivity()));
        
        // 限制返回数量
        if (limit > 0 && limit < activityDataList.size()) {
            return activityDataList.subList(0, limit);
        }
        
        return activityDataList;
    }
    
    /**
     * 获取周活跃度排行榜
     * @param limit 返回数量限制
     * @return 排行榜数据
     */
    public List<ActivityData> getWeeklyRankings(int limit) {
        List<ActivityData> activityDataList = new ArrayList<>(activityDataMap.values());
        
        // 按周活跃度降序排序
        activityDataList.sort((a1, a2) -> Integer.compare(a2.getWeeklyActivity(), a1.getWeeklyActivity()));
        
        // 限制返回数量
        if (limit > 0 && limit < activityDataList.size()) {
            return activityDataList.subList(0, limit);
        }
        
        return activityDataList;
    }
    
    /**
     * 获取连续登录排行榜
     * @param limit 返回数量限制
     * @return 排行榜数据
     */
    public List<ActivityData> getConsecutiveLoginRankings(int limit) {
        List<ActivityData> activityDataList = new ArrayList<>(activityDataMap.values());
        
        // 按连续登录天数降序排序
        activityDataList.sort((a1, a2) -> Integer.compare(a2.getConsecutiveLogins(), a1.getConsecutiveLogins()));
        
        // 限制返回数量
        if (limit > 0 && limit < activityDataList.size()) {
            return activityDataList.subList(0, limit);
        }
        
        return activityDataList;
    }
    
    /**
     * 获取活跃度数据列表，按月活跃度排序
     * @param limit 限制返回数量
     * @return 活跃度数据列表
     */
    public List<ActivityData> getActivityDataList(int limit) {
        List<ActivityData> activityDataList = new ArrayList<>(activityDataMap.values());
        
        // 按月活跃度降序排序
        activityDataList.sort((a1, a2) -> Integer.compare(a2.getMonthlyActivity(), a1.getMonthlyActivity()));
        
        // 限制返回数量
        if (limit > 0 && limit < activityDataList.size()) {
            return activityDataList.subList(0, limit);
        }
        
        return activityDataList;
    }
} 